<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>阿拉伯语右排布局 | Blog</title>
    <meta name="generator" content="VuePress 1.9.10">
    <link rel="icon" href="/blog/img/logo.png">
    <link rel="manifest" href="/blog/manifest.json">
    <link rel="apple-touch-icon" href="/blog/icons/apple-touch-icon-152x152.png">
    <link rel="mask-icon" href="/blog/icons/safari-pinned-tab.svg" color="#3eaf7c">
    <meta name="description" content="blog | js | node | vue | vuepress | webpack">
    <meta name="theme-color" content="#3eaf7c">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="msapplication-TileImage" content="/icons/msapplication-icon-144x144.png">
    <meta name="msapplication-TileColor" content="#000000">
    
    <link rel="preload" href="/blog/assets/css/0.styles.b6b82f87.css" as="style"><link rel="preload" href="/blog/assets/js/app.43c5da00.js" as="script"><link rel="preload" href="/blog/assets/js/2.d3a12b6d.js" as="script"><link rel="preload" href="/blog/assets/js/1.f8bb34da.js" as="script"><link rel="preload" href="/blog/assets/js/30.6e4a155b.js" as="script"><link rel="prefetch" href="/blog/assets/js/10.fde088a2.js"><link rel="prefetch" href="/blog/assets/js/11.c62b6b34.js"><link rel="prefetch" href="/blog/assets/js/12.27d4f152.js"><link rel="prefetch" href="/blog/assets/js/13.419d7748.js"><link rel="prefetch" href="/blog/assets/js/14.eb7a3d07.js"><link rel="prefetch" href="/blog/assets/js/15.114dfd5c.js"><link rel="prefetch" href="/blog/assets/js/16.85253907.js"><link rel="prefetch" href="/blog/assets/js/17.c2838453.js"><link rel="prefetch" href="/blog/assets/js/18.3256f17f.js"><link rel="prefetch" href="/blog/assets/js/19.d8afd0ae.js"><link rel="prefetch" href="/blog/assets/js/20.0d880388.js"><link rel="prefetch" href="/blog/assets/js/21.33b300c9.js"><link rel="prefetch" href="/blog/assets/js/22.4137860d.js"><link rel="prefetch" href="/blog/assets/js/23.b74cc977.js"><link rel="prefetch" href="/blog/assets/js/24.d99ad412.js"><link rel="prefetch" href="/blog/assets/js/25.ca9a652b.js"><link rel="prefetch" href="/blog/assets/js/26.66d6bac4.js"><link rel="prefetch" href="/blog/assets/js/27.95990a8e.js"><link rel="prefetch" href="/blog/assets/js/28.761c6ea4.js"><link rel="prefetch" href="/blog/assets/js/29.254ffe48.js"><link rel="prefetch" href="/blog/assets/js/3.af33e5d6.js"><link rel="prefetch" href="/blog/assets/js/31.665d02a7.js"><link rel="prefetch" href="/blog/assets/js/32.45b461b5.js"><link rel="prefetch" href="/blog/assets/js/33.17a0771a.js"><link rel="prefetch" href="/blog/assets/js/34.af9f8240.js"><link rel="prefetch" href="/blog/assets/js/35.e9dd53af.js"><link rel="prefetch" href="/blog/assets/js/36.e900b84a.js"><link rel="prefetch" href="/blog/assets/js/37.52783c0e.js"><link rel="prefetch" href="/blog/assets/js/38.5cb7cb7f.js"><link rel="prefetch" href="/blog/assets/js/39.0d72378d.js"><link rel="prefetch" href="/blog/assets/js/4.0a92875f.js"><link rel="prefetch" href="/blog/assets/js/40.dfcfa312.js"><link rel="prefetch" href="/blog/assets/js/41.3ae8c9d7.js"><link rel="prefetch" href="/blog/assets/js/42.bed07f3e.js"><link rel="prefetch" href="/blog/assets/js/43.170da95d.js"><link rel="prefetch" href="/blog/assets/js/44.eec82bc0.js"><link rel="prefetch" href="/blog/assets/js/45.b5a61f3a.js"><link rel="prefetch" href="/blog/assets/js/46.dbdb669f.js"><link rel="prefetch" href="/blog/assets/js/47.f3b25bee.js"><link rel="prefetch" href="/blog/assets/js/48.6c3ba867.js"><link rel="prefetch" href="/blog/assets/js/49.2c3070ea.js"><link rel="prefetch" href="/blog/assets/js/5.3b9be48d.js"><link rel="prefetch" href="/blog/assets/js/50.4a2a7438.js"><link rel="prefetch" href="/blog/assets/js/51.b3b493a3.js"><link rel="prefetch" href="/blog/assets/js/52.a56b61d7.js"><link rel="prefetch" href="/blog/assets/js/53.8f36ae1d.js"><link rel="prefetch" href="/blog/assets/js/54.8ee09618.js"><link rel="prefetch" href="/blog/assets/js/55.527c5d9c.js"><link rel="prefetch" href="/blog/assets/js/56.a09690f4.js"><link rel="prefetch" href="/blog/assets/js/57.cf4bc588.js"><link rel="prefetch" href="/blog/assets/js/58.0c8b9d19.js"><link rel="prefetch" href="/blog/assets/js/59.7d09c3f1.js"><link rel="prefetch" href="/blog/assets/js/6.7b96ebf4.js"><link rel="prefetch" href="/blog/assets/js/60.52e5c6db.js"><link rel="prefetch" href="/blog/assets/js/61.afa66052.js"><link rel="prefetch" href="/blog/assets/js/62.d7a75678.js"><link rel="prefetch" href="/blog/assets/js/63.77765300.js"><link rel="prefetch" href="/blog/assets/js/64.9777d386.js"><link rel="prefetch" href="/blog/assets/js/65.deeca199.js"><link rel="prefetch" href="/blog/assets/js/66.aba723e9.js"><link rel="prefetch" href="/blog/assets/js/67.47b5088b.js"><link rel="prefetch" href="/blog/assets/js/68.3178dffd.js"><link rel="prefetch" href="/blog/assets/js/69.a0f4810a.js"><link rel="prefetch" href="/blog/assets/js/7.7e58b9c4.js"><link rel="prefetch" href="/blog/assets/js/70.5b120c62.js"><link rel="prefetch" href="/blog/assets/js/71.2335838f.js"><link rel="prefetch" href="/blog/assets/js/vendors~docsearch.2493936b.js">
    <link rel="stylesheet" href="/blog/assets/css/0.styles.b6b82f87.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/blog/" class="home-link router-link-active"><!----> <span class="site-name">Blog</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/blog/" class="nav-link">
  home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="long-ui" class="dropdown-title"><span class="title">long-ui</span> <span class="arrow down"></span></button> <button type="button" aria-label="long-ui" class="mobile-dropdown-title"><span class="title">long-ui</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/ui/" class="nav-link">
  UI简介
</a></li><li class="dropdown-item"><!----> <a href="https://weberlong.github.io/long-ui/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  预览
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/WeberLong/long-ui" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><a href="/blog/archives/" class="nav-link router-link-active">
  archives
</a></div><div class="nav-item"><a href="/blog/interview/" class="nav-link">
  interview
</a></div> <a href="https://github.com/WeberLong" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/blog/" class="nav-link">
  home
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="long-ui" class="dropdown-title"><span class="title">long-ui</span> <span class="arrow down"></span></button> <button type="button" aria-label="long-ui" class="mobile-dropdown-title"><span class="title">long-ui</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/ui/" class="nav-link">
  UI简介
</a></li><li class="dropdown-item"><!----> <a href="https://weberlong.github.io/long-ui/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  预览
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://github.com/WeberLong/long-ui" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><a href="/blog/archives/" class="nav-link router-link-active">
  archives
</a></div><div class="nav-item"><a href="/blog/interview/" class="nav-link">
  interview
</a></div> <a href="https://github.com/WeberLong" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><a href="/blog/archives/" class="sidebar-heading clickable router-link-active open"><span>我的文章</span> <!----></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/archives/component.html" class="sidebar-link">Vue组件开发</a></li><li><a href="/blog/archives/webpack.html" class="sidebar-link">Webpack简介</a></li><li><a href="/blog/archives/rtlcss.html" aria-current="page" class="active sidebar-link">阿拉伯语右排布局</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/blog/archives/rtlcss.html#右排布局概述" class="sidebar-link">右排布局概述</a></li><li class="sidebar-sub-header"><a href="/blog/archives/rtlcss.html#rtl布局两种方案" class="sidebar-link">RTL布局两种方案</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/blog/archives/rtlcss.html#方案一-基于transform镜像" class="sidebar-link">方案一: 基于transform镜像</a></li><li class="sidebar-sub-header"><a href="/blog/archives/rtlcss.html#方案二-基于direction属性" class="sidebar-link">方案二: 基于direction属性</a></li></ul></li><li class="sidebar-sub-header"><a href="/blog/archives/rtlcss.html#结论" class="sidebar-link">结论</a></li></ul></li><li><a href="/blog/archives/monitor.html" class="sidebar-link">性能与错误监控方案</a></li><li><a href="/blog/archives/performance.html" class="sidebar-link">前端性能优化</a></li><li><a href="/blog/archives/recode.html" class="sidebar-link">Docs重构</a></li><li><a href="/blog/archives/cach.html" class="sidebar-link">理解浏览器缓存</a></li><li><a href="/blog/archives/httpcode.html" class="sidebar-link">HTTP 状态码</a></li><li><a href="/blog/archives/vite.html" class="sidebar-link">vite介绍</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="阿拉伯语右排布局"><a href="#阿拉伯语右排布局" class="header-anchor">#</a> 阿拉伯语右排布局</h1> <h2 id="右排布局概述"><a href="#右排布局概述" class="header-anchor">#</a> 右排布局概述</h2> <p>在普通的网页里，阅读方向是从左往右，但阿拉伯语的阅读方向是从右往左。通过查看阿拉伯语网站和<code>Google</code>的<a href="https://www.mdui.org/design/usability/bidirectionality.html" target="_blank" rel="noopener noreferrer">Material Design双向性文章<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，对比从左到右（LTR）语言网站，从右到左（RTL）语言的网站特点：</p> <ul><li>排版是从右往左</li> <li>文本是向右对齐且从右往左阅读，文本方向始终和语言保持一致，比如数字(电话号码、时间)</li> <li>方向性图标和LTR相反，其他的图标和图片不会镜像
<img src="/blog/img/rtl_0.jpg"></li></ul> <p>通过上面知道RTL布局的特点后，我们在现有的项目里支持RTL布局需要考虑：</p> <ul><li>以低成本、代码入侵少、可兼容、可维护的改造线上的代码支持RTL布局</li> <li>对于未来新增的页面功能能快速支持LTR和RTL布局</li></ul> <h2 id="rtl布局两种方案"><a href="#rtl布局两种方案" class="header-anchor">#</a> RTL布局两种方案</h2> <h3 id="方案一-基于transform镜像"><a href="#方案一-基于transform镜像" class="header-anchor">#</a> 方案一: 基于<code>transform</code>镜像</h3> <p>通过<code>transform</code>的镜像翻转，使用<code>CSS3</code>的<code>transform</code>属性，通过<code>transform: scaleX(-1)</code>可以使页面沿着X轴进行水平翻转,可以快速的解决布局镜像的问题，思路：</p> <ul><li>在阿拉伯语页面上添加上全局翻转：<div class="language-css extra-class"><pre class="language-css"><code><span class="token comment">/* xx/index.css */</span>
<span class="token selector">html[lang=&quot;ar&quot;]</span> <span class="token punctuation">{</span>
  <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scaleX</span><span class="token punctuation">(</span>-1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li>将页面中不需要翻转的内容进行包裹<div class="language-css extra-class"><pre class="language-css"><code><span class="token comment">/* xx/index.css */</span>
<span class="token selector">html[lang=&quot;ar&quot;] .not-flip</span> <span class="token punctuation">{</span>
  <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scaleX</span><span class="token punctuation">(</span>-1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul> <p>处理后的效果如下:
<img src="/blog/img/rtl_1.png"></p> <p><code>transform</code>方案优点是无需修改js逻辑，只需要处理css；缺点是我们有五个项目，PC端和移动端，代码入侵大，工作量大，所有涉及到文本和图片的地方都需要进行处理。</p> <h3 id="方案二-基于direction属性"><a href="#方案二-基于direction属性" class="header-anchor">#</a> 方案二: 基于<code>direction</code>属性</h3> <p><code>direction</code>与在<code>html</code>标签上直接添加<code>dir=&quot;rtl&quot;</code>的作用一样，可以改变我们网站的布局，<code>CSS</code>手册中对<code>direction</code>属性是这样描述的：该属性指定了块的基本书写方向，以及针对<code>Unicode</code>双向算法的嵌入和覆盖方向。通俗的讲，排版改成从右往左，文字和图片方向不变。
我们在github上找到<code>postcss-rtl</code>开源插件，它的原理就是对<code>CSS</code>文件进行处理，比如将 <code>CSS</code>属性中的<code>left</code>改为<code>right</code>，<code>right</code>改为<code>left</code>。</p> <div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">[dir] .foo</span> <span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">[dir=&quot;ltr&quot;] .foo</span> <span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">[dir=&quot;rtl&quot;] .foo</span> <span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>基于<code>direction</code>属性RTL布局方案：</p> <ul><li><code>webpack</code>中引入插件<a href="https://github.com/vkalinichev/postcss-rtl" target="_blank" rel="noopener noreferrer">postcss-rtl<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> <ul><li><code>vue-cli2</code>脚手架配置:
安装依赖<code>yarn add postcss-loader postcss-rtl -D</code>
在<code>webpack</code>中(<code>cloud/build/utils.js</code>)文件里添加<code>postcss-loader</code>的插件<code>postcss-rtl</code><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> postcssLoader <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">loader</span><span class="token operator">:</span> <span class="token string">'postcss-loader'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">postcssOptions</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">[</span> <span class="token string">'postcss-rtl'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">]</span> <span class="token comment">// 添加阿拉伯语右排布局插件</span>
      <span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// generate loader string to be used with extract text plugin</span>
<span class="token keyword">function</span> <span class="token function">generateLoaders</span><span class="token punctuation">(</span><span class="token parameter">loader<span class="token punctuation">,</span> loaderOptions</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> loaders <span class="token operator">=</span> <span class="token punctuation">[</span>cssLoader<span class="token punctuation">,</span> autoprefixerLoader<span class="token punctuation">,</span> postcssLoader<span class="token punctuation">]</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>loader<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    loaders<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      <span class="token literal-property property">loader</span><span class="token operator">:</span> loader <span class="token operator">+</span> <span class="token string">'-loader'</span><span class="token punctuation">,</span>
      <span class="token literal-property property">options</span><span class="token operator">:</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> loaderOptions<span class="token punctuation">,</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">sourceMap</span><span class="token operator">:</span> options<span class="token punctuation">.</span>sourceMap
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token operator">...</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><code>vue-cli3</code>脚手架配置:
安装依赖<code>yarn add postcss-rtl -D</code>
在<code>webpack</code>中(<code>apps-moblie-docs/vue.config.js</code>)文件里添加<code>postcss-rtl</code>插件<div class="language-js extra-class"><pre class="language-js"><code><span class="token literal-property property">css</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">sourceMap</span><span class="token operator">:</span> <span class="token operator">!</span>isProduction<span class="token punctuation">,</span>
  <span class="token literal-property property">loaderOptions</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">postcss</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'postcss-rtl'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 添加阿拉伯语右排布局插件</span>
      <span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul></li> <li><code>html</code>标签属性添加默认值<code>dir=&quot;ltr&quot;</code>, 比如: <code>&lt;html dir=&quot;ltr&quot;&gt;</code></li> <li>在<code>app.vue</code>入口里添加根据语言判断修改html的dir属性，比如: <code>document.documentElement.setAttribute('dir', this.$i18n.locale === 'ar' ? 'rtl' : 'ltr')</code></li> <li>方向的图标处理：<div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">// 适配右排布局图标方向
[dir=rtl]</span><span class="token punctuation">{</span>
  <span class="token selector">.components-icons</span><span class="token punctuation">{</span>
    <span class="token selector">&amp;.components-icons-back</span><span class="token punctuation">{</span>
      <span class="token selector">&amp;:before</span> <span class="token punctuation">{</span>
        <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scaleX</span><span class="token punctuation">(</span>-1<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li>元素拼接的语句的处理：<div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">// 适配右排布局
[dir=rtl]</span> <span class="token punctuation">{</span>
  <span class="token selector">.yun-row__desc</span> <span class="token punctuation">{</span>
    <span class="token property">direction</span><span class="token punctuation">:</span> ltr<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> inline-flex<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> flex-end<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul> <p>处理后的效果如下:
<img src="/blog/img/rtl_2.png"></p> <p><code>direction</code>方案优点是工作量减少，代码入侵减少；缺点是需要处理方向性的图标的方向和被元素拼接的语句(断句)。</p> <h2 id="结论"><a href="#结论" class="header-anchor">#</a> 结论</h2> <table><thead><tr><th>方案</th> <th>优点</th> <th>缺点</th></tr></thead> <tbody><tr><td><code>transform</code></td> <td>无需修改<code>js</code>逻辑，只需要处理<code>css</code></td> <td>代码入侵大，工作量大</td></tr> <tr><td><code>direction</code></td> <td>工作量减少，代码入侵减少</td> <td>处理方向性的图标的方向和被元素拼接的语句(断句)</td></tr></tbody></table> <p>综合<code>transform</code>和<code>direction</code>方案各方面比较，<code>direction</code>方案的工作量减少、代码入侵少，最后决定使用<code>direction</code>方案。</p></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/blog/archives/webpack.html" class="prev">
        Webpack简介
      </a></span> <span class="next"><a href="/blog/archives/monitor.html">
        性能与错误监控方案
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/blog/assets/js/app.43c5da00.js" defer></script><script src="/blog/assets/js/2.d3a12b6d.js" defer></script><script src="/blog/assets/js/1.f8bb34da.js" defer></script><script src="/blog/assets/js/30.6e4a155b.js" defer></script>
  </body>
</html>
